Skip to main content
Version: 1.0.0

licenseHasExpired

Email Templates​

License ExpiredGrace Period Expired
License Expired TemplateGrace License Expired Template
30 Days Warning60 Days Warning
30 Days Warning Template60 Days Warning Template

Function Names: licenseHasExpired / testLicenseHasExpired

Author: Domenico Cerone Creation Date: 25/09/2025
Last Reviewer: Domenico Cerone

Trigger: Scheduler (onSchedule - daily at 18:00) / HTTPS (onRequest)

Purpose: Daily notification system for license management in ARShades Subscription System. This Cloud Function checks licenses daily and sends notifications to clients at key moments. It uses ZeptoMail as the primary email system and Nodemailer as fallback with specific templates for different notification types.

Detailed Functionality​

1. TRIGGER AND SCHEDULING​

  • Automatic execution daily at 18:00 (Europe/Rome timezone)
  • Can be executed manually via HTTP endpoint for testing
  • Execution region: europe-central2

2. LICENSE RETRIEVAL AND ANALYSIS​

  • Queries 'ARShadesSubscriptions' collection for all licenses
  • Filters only licenses with "Active" or "Expired" status
  • Verifies presence of valid expiration date
  • Handles different timestamp formats for expiration date
  • Calculates remaining days until expiration

3. PRELIMINARY OPTIMIZATION​

  • Checks if notifications need to be sent BEFORE expensive database queries
  • Verifies if license is at 60 days, 30 days from expiration, just expired, or 15 days after expiration
  • Skips processing if no notification is needed

4. NOTIFICATION TYPES​

a. 60 Days Warning (SixtyDaysWarning)

  • Sent when exactly 60 days remain until expiration
  • Template: SIXTY_DAYS

b. 30 Days Warning (ThirtyDaysWarning)

  • Sent when exactly 30 days remain until expiration
  • Template: THIRTY_DAYS

c. Expiration Notification (Expired)

  • Sent when license expires (endDate reached)
  • Updates license status to 'Expired'
  • Template: EXPIRED

d. Grace Period End Notification (GracePeriodEnd)

  • Sent 15 days after expiration
  • Verifies that status is 'Expired'
  • Template: GRACE_PERIOD_END

5. PRELIMINARY CHECKS​

  • Verifies if email sending is blocked (blockSendMail = true)
  • Checks if notification of same type was already sent
  • Verifies presence of client reference (clientRef)

6. CLIENT DATA AND PROFILES RETRIEVAL​

  • Retrieves client document from 'Client' collection
  • Gets list of catalogs associated with license (supports different storage formats)
  • Extracts associated profiles (allProfileList and mainProfileList)

7. NOTIFICATION PREFERENCE CHECK​

  • For each profile in allProfileList, checks if licenseHasExpired notification is enabled
  • Verifies notification_types.licenseHasExpired field in each profile
  • If notification is disabled (false): skips that profile without sending email
  • If notification is enabled (true): proceeds with access verification
  • Provides clear logging about notification preference status for each profile

8. EMAIL RECIPIENTS SELECTION (UPDATED LOGIC)​

  • For each profile in allProfileList, verifies access to license catalogs
  • IMPORTANT: Selects ONLY profiles with 'Cliente' role (excludes Admin, etc.)
  • Verifies intersection between profile catalogs and license catalogs
  • NEW LOGIC: If no profile has specific access BUT profiles exist in mainProfileList, email is still sent
  • SKIPS ONLY if: profilesWithAccess.length === 0 AND mainProfileList.length === 0
  • Logs debug details for each analyzed profile
  • Handles errors for profiles not found or not accessible

9. EMAIL DATA PREPARATION​

  • Formats expiration and grace period dates in Italian format
  • Retrieves main profile information for personalization
  • Prepares TO (profiles with access), CC (main profiles) and BCC (admin) recipients
  • FIX APPLIED: Resolved licenseName/formattedLicenseName variable scoping conflict

10. EMAIL SENDING WITH ZEPTOMAIL​

  • Uses appropriate template for each notification type
  • Passes necessary variables to template (license name, main profile, dates)
  • Handles TO, CC and BCC with full names when available

11. IMPROVED FALLBACK HANDLING​

  • In case of ZeptoMail error, uses Nodemailer with specific templates for each notification type
  • NEW FALLBACK TEMPLATES:
    • SixtyDaysWarning: "Warning: License will expire in 60 days" (orange)
    • ThirtyDaysWarning: "Urgent: License will expire in 30 days" (dark orange)
    • Expired: "EXPIRED: License expired today" (red, with grace period info)
    • GracePeriodEnd: "CRITICAL: Grace period ended" (dark red, service suspended)
  • Professional HTML templates with appropriate colors and clean layout
  • Correct dates and content for each scenario (future expiration vs already expired)
  • Sent only to profiles in mainProfileList
  • Logs errors from both main system and fallback

12. LICENSE DOCUMENT UPDATE​

  • After successful sending, updates 'notifications' array
  • Adds new object with specific notification type and sendDate
  • If expiration notification, also updates status to 'Expired'

13. ADVANCED LOGGING AND MONITORING​

  • Logs complete details of each process phase
  • Tracks successes, errors and fallback attempts
  • Produces categorized final summary (emails sent, no action, skipped, etc.)
  • Provides aggregate statistics by result type

Input (Payload)​

Scheduler Function (licenseHasExpired)​

  • Automatic trigger: No input required (scheduled execution)
  • Schedule: Daily at 18:00 Europe/Rome timezone

HTTP Function (testLicenseHasExpired)​

  • Method: GET
  • Headers: None required
  • Body: None required
  • Parameters: None required

Output (Success)​

Scheduler Function​

{
"success": true,
"processed": true,
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true
}
]
}

HTTP Function​

{
"success": true,
"message": "Controllo licenze scadute completato con successo",
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true,
"fallback": false
}
]
}

Response Properties:

  • success (boolean): Indicates if the operation was completed successfully
  • message (string): Descriptive message about the operation result
  • results (array): Array of processed licenses with details
  • licenseId (string): Unique identifier of the processed license
  • licenseName (string): Name and type of the license
  • recipients (array): List of email addresses that received the notification
  • fallback (boolean): Indicates if Nodemailer fallback was used

Testing​

URL (if HTTPS)​

Development: http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired

Test with Emulator​

  1. Start Firebase emulators:

    firebase emulators:start --only functions
  2. Set Node.js version:

    nvm use 20
  3. Test with curl:

    curl "http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired"

Postman Testing​

  • Method: GET
  • URL: http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired
  • Headers: None required
  • Body: None required

Deploy Command​

firebase deploy --only functions:licenseHasExpired,functions:testLicenseHasExpired

Production URL​

Scheduled Function: https://europe-central2-arshades-7e18a.cloudfunctions.net/licenseHasExpired (Reference only - not directly callable)

Test Function: https://europe-central2-arshades-7e18a.cloudfunctions.net/testLicenseHasExpired

MAIL_TEMPLATE_KEYS​

  • EXPIRED: 13ef.8598f19fbcc5adb.k1.9902c130-46a8-11f0-900d-dad70ff08860.1975e5ffcc38
  • SIXTY_DAYS: 13ef.8598f19fbcc5adb.k1.c7e1eee0-46d0-11f0-900d-dad70ff08860.1975f6754ce
  • THIRTY_DAYS: 13ef.8598f19fbcc5adb.k1.dec244d1-46d4-11f0-900d-dad70ff08860.1975f82218d
  • GRACE_PERIOD_END: 13ef.8598f19fbcc5adb.k1.13d51510-46d7-11f0-900d-dad70ff08860.1975f9098e1